package kr.ac.kaist.ysproject.service;

import java.util.ArrayList;
import java.util.Calendar;

import kr.ac.kaist.ysproject.data.DataMsgHistory;
import kr.ac.kaist.ysproject.data.DataProfile;
import kr.ac.kaist.ysproject.data.DataSmartMsgInfo;
import kr.ac.kaist.ysproject.util.DbManager;
import android.app.Activity;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Binder;
import android.os.ConditionVariable;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.telephony.SmsManager;
import android.util.Log;
import android.widget.Toast;

public class SmsSenderService extends Service {
	private ConditionVariable mCondition;
	private DbManager m_dbm;
	
	@Override
	public void onCreate() {
		Log.d("SmsSenderService", "OnCreate() Started");
		
		m_dbm = DbManager.getInstance(SmsSenderService.this);
		
		Thread thr = new Thread(null, mTask, "SmsSenderService");
		mCondition = new ConditionVariable(false); //Thread의 실행을 제어할 변수
		thr.start(); //Thread 시작
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.d("SmsSenderService", "onStartCommand() Started");

		return 0;
	}

	@Override
	public void onDestroy() {
		Log.d("SmsSenderService", "OnDestroy() Started");
		
		// Stop the thread from generating further notifications
		// 이전에 실행됐던 Thread 들을 모두 중지시킵니다.
		mCondition.open();
	}
	
    private Runnable mTask = new Runnable() {
        public void run() {
        	
        	Log.d("SmsSenderService", "run()");

            while(true) {
            	Log.d("SmsSenderService", "Run() loop");
            	
            	ArrayList<DataSmartMsgInfo> msgInfo = m_dbm.getSmartMsgInfoForAlarm();
            	
            	for (int i = 0; i < msgInfo.size(); i++) {
            		
            		DataSmartMsgInfo smartMsgInfo = msgInfo.get(i);
            		
        			// 메시지 직접 입력이 있는 경우
        			DataProfile profile = m_dbm.getProfileById(smartMsgInfo.getProfId());
        			Log.e("SmsSenderService", "PhoneNo = " + profile.getMobileNo());
        			
        			if (profile == null) {
        				Log.e("SmsSenderService", "No Profile Information");
        				continue;
        			}
            		
            		if (smartMsgInfo.getManualMsg().equals("")) {
            			// 내장 메시지 사용하는 경우
            			String internalMsg = m_dbm.getInternalMsgByRand(smartMsgInfo.getCategory()
            					, smartMsgInfo.getRespect()
            					, smartMsgInfo.getTalkingWay());
            			
            			if (internalMsg == null) {
            				Log.e("SmsSenderService", "InternalMsg is null");
            				continue;
            			} else {
                			Log.e("SmsSenderService", "Internal Msg = " + internalMsg);
                			
                			sendSMS(profile.getMobileNo(), internalMsg);
                			
                			DataMsgHistory msgHistory = new DataMsgHistory();
                			
                			Calendar calendar = Calendar.getInstance();
                			String curDate = new String().format("%04d.%02d.%02d"
    								, calendar.get(Calendar.YEAR)
    								, calendar.get(Calendar.MONTH) + 1
    								, calendar.get(Calendar.DAY_OF_MONTH));
                			
                			String curTime = new String().format("%02d:%02d:%02d", 
                					calendar.get(Calendar.HOUR_OF_DAY),
                					calendar.get(Calendar.MINUTE),
                					calendar.get(Calendar.SECOND));
                			
                			Log.d("SmsSenderService", "sentDate = " + curDate + " " + curTime);
                			
                			msgHistory.setSentDate(curDate + " " + curTime);
                			msgHistory.setMsg(internalMsg);
                			msgHistory.setProfId(Integer.toString(profile.getId()));
                			
                			m_dbm.saveMsgHistory(msgHistory);
            			}
            		} else {
            			Log.e("SmsSenderService", "Manual Msg = " + smartMsgInfo.getManualMsg());
            			
            			sendSMS(profile.getMobileNo(), smartMsgInfo.getManualMsg());
            			
            			DataMsgHistory msgHistory = new DataMsgHistory();
            			
            			Calendar calendar = Calendar.getInstance();
            			String curDate = new String().format("%04d.%02d.%02d"
								, calendar.get(Calendar.YEAR)
								, calendar.get(Calendar.MONTH) + 1
								, calendar.get(Calendar.DAY_OF_MONTH));
            			
            			String curTime = new String().format("%02d:%02d:%02d", 
            					calendar.get(Calendar.HOUR_OF_DAY),
            					calendar.get(Calendar.MINUTE),
            					calendar.get(Calendar.SECOND));
            			
            			Log.d("SmsSenderService", "sentDate = " + curDate + " " + curTime);
            			
            			msgHistory.setSentDate(curDate + " " + curTime);
            			msgHistory.setMsg(smartMsgInfo.getManualMsg());
            			msgHistory.setProfId(Integer.toString(profile.getId()));
            			
            			m_dbm.saveMsgHistory(msgHistory);
            		}
            	}
            	
                //60초간 Thread의 실행을 중지시킵니다.
                if (mCondition.block(60 * 1000)) 
                    break;
            }

            // Done with our work...  stop the service!
            SmsSenderService.this.stopSelf();
        }
    };

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    // This is the object that receives interactions from clients.  See
    // RemoteService for a more complete example.
    private final IBinder mBinder = new Binder() {
        @Override
        protected boolean onTransact(int code, Parcel data, Parcel reply,
                int flags) throws RemoteException {
            return super.onTransact(code, data, reply, flags);
        }
    };

    private void sendSMS(String phoneNumber, String message) {
    	String SENT = "SMS_SENT";
    	String DELIVERED = "SMS_DELIVERED";
    	
    	Log.d("SmsSenderService", "sendSMS() started");
    	
    	PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(SENT), 0);
    	PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0, new Intent(DELIVERED), 0);
    	
    	registerReceiver(new BroadcastReceiver() {
    		
    		@Override
    		public void onReceive(Context arg0, Intent arg1) {
    			switch (getResultCode()) {
    			case Activity.RESULT_OK:
    				Toast.makeText(getBaseContext(), "SMS sent", Toast.LENGTH_SHORT).show();
    				break;
    			case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
    				Toast.makeText(getBaseContext(), "Generic failure", Toast.LENGTH_SHORT).show();
    				break;
    			case SmsManager.RESULT_ERROR_NO_SERVICE:
    				Toast.makeText(getBaseContext(), "No service", Toast.LENGTH_SHORT).show();
    				break;
    			case SmsManager.RESULT_ERROR_NULL_PDU:
    				Toast.makeText(getBaseContext(), "Null PDU", Toast.LENGTH_SHORT).show();
    				break;
    			case SmsManager.RESULT_ERROR_RADIO_OFF:
    				Toast.makeText(getBaseContext(), "Radio off", Toast.LENGTH_SHORT).show();
    				break;

    			}
    		}
    	}, new IntentFilter(SENT));
    	
    	registerReceiver(new BroadcastReceiver() {
    		@Override
    		public void onReceive(Context arg0, Intent arg1) {
    			switch (getResultCode()) {
    			case Activity.RESULT_OK:
    				Toast.makeText(getBaseContext(), "SMS delivered", Toast.LENGTH_SHORT).show();
    				break;
    			case Activity.RESULT_CANCELED:
    				Toast.makeText(getBaseContext(), "SMS not delivered", Toast.LENGTH_SHORT).show();
    				break;
    			}
    		}
    	}, new IntentFilter(DELIVERED));
    	
    	SmsManager sms = SmsManager.getDefault();
    	sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);
    	
    	Log.d("SmsSenderService", "sendSMS() ended");
    }
}
